package com.zlzlib.librxoknet.base;

import com.zlzlib.librx.listener.ProgressListener;
import com.zlzlib.librxoknet.pro.ProRequestBody;
import com.zlzlib.librxoknet.pro.ProResponseBody;

import java.io.IOException;
import java.util.Map;
import java.util.WeakHashMap;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okio.Buffer;

/**
 * Created by zlz on 2019/8/21.
 * 带进度的请求器
 */
public abstract class BaseProRetrofit<T> extends BaseRetrofit<T> {

    //上传和下载进度的地址集合
    private final Map<String, ProgressListener<Buffer>> loadProMap = new WeakHashMap<>();

    /**
     * @Desc: 进度拦截器
     * @DateTime: 2020/7/14 11:22
     * @Author zlz
     */
    private final class LoadInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = wrapRequest(chain.request());
            return wrapResponse(chain.proceed(request));
        }

        /**
         * 上传进度
         */
        private Request wrapRequest(Request request) {
            if (request == null || request.body() == null) {
                return request;
            }
            ProgressListener listener = request.tag(ProgressListener.class);
            if (listener == null) {
                synchronized (BaseProRetrofit.class) {
                    listener = loadProMap.get(request.url().toString());
                }
                if (listener == null) {
                    return request;
                }
            }
            Request.Builder builder = request.newBuilder();
            builder.method(request.method(), new ProRequestBody(request.body(), listener, freshTime()));
            return builder.build();
        }

        /**
         * 下载进度
         */
        private Response wrapResponse(Response response) {
            if (response == null || response.body() == null) {
                return response;
            }
            Request request = response.request();
            ProgressListener listener = response.request().tag(ProgressListener.class);
            if (listener == null) {
                synchronized (BaseProRetrofit.class) {
                    listener = loadProMap.get(request.url().toString());
                }
                if (listener == null) {
                    return response;
                }
            }
            Response.Builder builder = response.newBuilder();
            builder.body(new ProResponseBody(response.body(), listener, freshTime()));
            return builder.build();
        }
    }


    /**
     * @Desc :刷新进度时间间隔 单位  ms
     * @DateTime: 2020/7/14 11:23
     * @Author zlz
     */
    protected long freshTime() {
        return 500;
    }

    @Override
    protected OkHttpClient.Builder settingClient(OkHttpClient.Builder builder) {
        //添加进度监听的拦截器
        return builder.addNetworkInterceptor(new LoadInterceptor());
    }

    /**
     * 添加上传和下载进度监听
     * 将这个{@link com.zlzlib.librx.listener.ProgressListener} 对象放到 请求{@link okhttp3.Request}  的tag里面
     */
    public BaseProRetrofit<T> addLoadProgressListener() {
        return this;
    }

    /**
     * 添加上传和下载进度监听
     * 通过url来监听  如果需要下载或上传同一个地址  监听请使用 上面设置tag的方法监听
     */
    public BaseProRetrofit<T> addLoadProgressListener(String url, ProgressListener<Buffer> listener) {
        synchronized (BaseProRetrofit.class) {
            loadProMap.put(url, listener);
        }
        return this;
    }
}
